package net.zigin.nhi.could.waste.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.zigin.commons.util.AssertUtil;
import net.zigin.commons.util.StringUtil;
import net.zigin.nhi.could.waste.annotation.EpiResponseFilter;
import net.zigin.nhi.could.waste.annotation.EpiResponseFilters;
import net.zigin.nhi.could.waste.annotation.LoginWhitePathAnnotation;
import net.zigin.nhi.could.waste.constants.CommonConstants;
import net.zigin.nhi.could.waste.dto.QrCodeDto;
import net.zigin.nhi.could.waste.dto.SysUserDto;
import net.zigin.nhi.could.waste.exception.EpiCloudException;
import net.zigin.nhi.could.waste.exception.UnauthorizedException;
import net.zigin.nhi.could.waste.service.SysUserHospitalService;
import net.zigin.nhi.could.waste.service.SysUserService;

import net.zigin.nhi.could.waste.util.*;
import net.zigin.nhi.could.waste.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * SysUser控制器类
 *
 * @author mgw1986
 * @version V1.0
 * @ClassName: SysUserController
 * @date 2021-9-7 19:08:56
 */
@Api(tags = "登录注册")
@RestController
@RequestMapping("/sysUser")
public class SysUserController extends BaseController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserHospitalService sysUserHospitalService;

    /**
     * 账号密码登录
     * @param userDto name 登录账号
     *                password 登录密码
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("账号密码登录")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    @PostMapping("/login")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "activationTime,createTime,createUser,deleteTime,freezeTime,password", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "modifyTime,modifyUser,passwordTime,salt", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "isActivation,isDelete,isFreeze,isPassword", target = SysUserVo.class)
    })
    public JsonForResult<SysUserVo> login(@RequestBody SysUserDto userDto) {
        SysUserVo userVo = sysUserService.getUserByUserAccount(userDto.getName());
        if (userVo == null) {
            throw new EpiCloudException("用户不存在！");
        }
        if (SecurityUtil.matchesPassword(userDto.getPassword(),userVo.getPassword())) {
            SysUserVo info = sysUserService.getInfoById(userVo.getId());
            String userStaffId = sysUserHospitalService.getIdByUserId(userVo.getId());
            info.setUserStaffId(userStaffId);
            info.setToken(JWTUtil.sign(info));
            return JsonForResult.<SysUserVo>builder().data(info).success(true).build();
        } else {
            throw new EpiCloudException("密码错误！");
        }
    }

    /**
     * 修改账户密码
     *
     * @param userDto name 登录名
     *                password 密码
     *                oldPassword 旧密码
     * @return
     */
    @PostMapping("/modifyPassword")
    @ApiOperation("修改密码")
    @ApiImplicitParam(name = "userDto", value = "用户信息", required = true, dataType = "SysUserDto")
    public JsonForResult modifyPassword(@RequestBody SysUserDto userDto) {
        sysUserService.modifyPassword(userDto);
        return JsonForResult.builder().success(true).build();
    }

    /**
     * 发送二维码
     *
     * @param phone   电话
     * @param session
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("发送短信验证码码")
    @ApiImplicitParam(name = "phone", value = "电话", required = true, dataType = "String")
    @GetMapping("sendMessage")
    public JsonForResult sendMessage(String phone, HttpSession session) {
        String smsCode = AliYunUtil.sendMessage(phone);
        if (smsCode == null) {
            return JsonForResult.builder().message("验证码发送失败！请重新发送").success(false).build();
        }
        session.setAttribute(phone, smsCode);
        session.setMaxInactiveInterval(300); // 5分钟
        return JsonForResult.builder().success(true).build();
    }

    /**
     * 验证码登录
     *
     * @param phone   电话
     * @param smsCode 验证码
     * @param session
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("短信验证码登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "电话", required = true, dataType = "String"),
            @ApiImplicitParam(name = "smsCode", value = "验证码", required = true, dataType = "String")
    })
    @GetMapping("loginWithSmsCode")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "activationTime,createTime,createUser,deleteTime,freezeTime,password", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "modifyTime,modifyUser,passwordTime,salt", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "isActivation,isDelete,isFreeze,isPassword", target = SysUserVo.class)
    })
    public JsonForResult loginWithSmsCode(String phone, String smsCode, HttpSession session) {
        SysUserVo userVo = sysUserService.getUserByUserPhone(phone);
        Object code = session.getAttribute(phone);
        if (code != null && smsCode.equals(code.toString())) {
            SysUserVo info = sysUserService.getInfoById(userVo.getId());
            String userStaffId = sysUserHospitalService.getIdByUserId(userVo.getId());
            info.setUserStaffId(userStaffId);
            info.setToken(JWTUtil.sign(info));
            return JsonForResult.builder().data(info).success(true).build();
        } else {
            return JsonForResult.builder().message("401").success(false).build();
        }
    }

    /**
     * 扫码登录
     * @param qrCodeDto 二维码信息
     * @return
     */
    @LoginWhitePathAnnotation
    @ApiOperation("扫码登录")
    @ApiImplicitParam(name = "qrCodeDto", value = "二维码信息", required = true, dataType = "QrCodeDto")
    @PostMapping("loginWithQrCode")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "activationTime,createTime,createUser,deleteTime,freezeTime,password", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "modifyTime,modifyUser,passwordTime,salt", target = SysUserVo.class),
            @EpiResponseFilter(exclude = "isActivation,isDelete,isFreeze,isPassword", target = SysUserVo.class)
    })
    public JsonForResult loginWithQrCode(@RequestBody QrCodeDto qrCodeDto) {
        EncryptDataUtil.EncryptData encryptData = EncryptDataUtil.decryptData(qrCodeDto.getContent());
        AssertUtil.isNull(encryptData, "二维码解析错误！");
        if (encryptData.getType().equals(CommonConstants.QRCODE_USER_STAFF)) {
            String userId = encryptData.getData();
            String userStaffId = sysUserHospitalService.getIdByUserId(userId);
            SysUserVo info = sysUserService.getInfoById(userId);
            info.setUserStaffId(userStaffId);
            info.setToken(JWTUtil.sign(info));
            return JsonForResult.builder().data(info).success(true).build();
        }
        return JsonForResult.builder().message("401").success(false).build();

    }

    /**
     * 个人信息
     * @param id 员工id
     * @return 个人信息
     */
    @GetMapping("/getStaffInfoById/{id}")
    @ApiOperation("个人信息")
    @ApiImplicitParam(name = "id", value = "员工id", required = true, dataType = "String")
    @EpiResponseFilters({
            @EpiResponseFilter(exclude = "createTime,createUser", target = SysUserStaffVo.class),
            @EpiResponseFilter(exclude = "modifyTime,modifyUser", target = SysUserStaffVo.class)
    })
    public JsonForResult<SysUserStaffVo> getStaffInfoById(@PathVariable String id) {
        AssertUtil.isNull(id, "员工id不能为空");
        SysUserStaffVo info = sysUserHospitalService.getInfoById(id);
        return JsonForResult.<SysUserStaffVo>builder().data(info).success(true).build();
    }

    @GetMapping("/checkToken")
    @ApiOperation("验证token")
    public JsonForResult<String> checkToken(){
        return JsonForResult.<String>builder().data("success").success(true).build();
    }


}
